package com.jplus.plugins.j2cache;

import java.util.List;
import java.util.Properties;

import com.jplus.framework.core.ConfigHandle;
import com.jplus.plugins.j2cache.bean.CacheObject;
import com.jplus.plugins.j2cache.cache.J2CacheManager;
import com.jplus.plugins.j2cache.cache.iface.Cache;
import com.jplus.plugins.j2cache.fault.CacheException;

/**
 * 缓存入口
 * 
 * @author winterlau
 */
public class J2Cache {
	// ==========================================
	private final static byte LEVEL_1 = Cache.LEVEL_1;
	private final static byte LEVEL_2 = Cache.LEVEL_2;
	private static final J2CacheManager J2CACHE = new J2CacheManager();

	public static J2CacheManager getManager() {
		return J2CACHE;
	}

	public static Properties getConfig() {
		return ConfigHandle.getProp();
	}

	/**
	 * 获取缓存中的数据
	 */
	public static CacheObject get(String region, Object key) {
		CacheObject obj = new CacheObject();
		obj.setRegion(region);
		obj.setKey(key);
		if (region != null && key != null) {
			obj.setValue(J2CACHE.get(LEVEL_1, region, key));
			if (obj.getValue() == null) {
				obj.setValue(J2CACHE.get(LEVEL_2, region, key));
				if (obj.getValue() != null) {
					obj.setLevel(LEVEL_2);
					J2CACHE.set(LEVEL_1, region, key, obj.getValue());
				}
			} else
				obj.setLevel(LEVEL_1);
		}
		return obj;

	}

	/**
	 * 写入缓存
	 * 
	 * @param region
	 *            : Cache Region name
	 * @param key
	 *            : Cache key
	 * @param value
	 *            : Cache value
	 */
	public static void set(String region, Object key, Object value) {
		if (region != null && key != null) {
			if (value == null)
				evict(region, key);
			else {
				// 分几种情况
				// Object obj1 = CacheManager.get(LEVEL_1, region, key);
				// Object obj2 = CacheManager.get(LEVEL_2, region, key);
				// 1. L1 和 L2 都没有
				// 2. L1 有 L2 没有（这种情况不存在，除非是写 L2 的时候失败
				// 3. L1 没有，L2 有
				// 4. L1 和 L2 都有
				J2CACHE._sendEvictCmd(region, key);// 清除原有的一级缓存的内容
				J2CACHE.set(LEVEL_1, region, key, value);
				J2CACHE.set(LEVEL_2, region, key, value);
			}
		}
		// log.info("write data to cache region="+region+",key="+key+",value="+value);

	}

	/**
	 * 删除缓存
	 * 
	 * @param region
	 *            : Cache Region name
	 * @param key
	 *            : Cache key
	 */
	public static void evict(String region, Object key) {
		J2CACHE.evict(LEVEL_1, region, key); // 删除一级缓存
		J2CACHE.evict(LEVEL_2, region, key); // 删除二级缓存
		J2CACHE._sendEvictCmd(region, key); // 发送广播
	}

	/**
	 * 批量删除缓存
	 * 
	 * @param region
	 *            : Cache region name
	 * @param keys
	 *            : Cache key
	 */
	@SuppressWarnings({ "rawtypes" })
	public static void batchEvict(String region, List keys) {
		J2CACHE.batchEvict(LEVEL_1, region, keys);
		J2CACHE.batchEvict(LEVEL_2, region, keys);
		J2CACHE._sendEvictCmd(region, keys);
	}

	/**
	 * Clear the cache
	 * 
	 * @param region
	 *            : Cache region name
	 */
	public static void clear(String region) throws CacheException {
		J2CACHE.clear(LEVEL_1, region);
		J2CACHE.clear(LEVEL_2, region);
		J2CACHE._sendEvictCmd(region, "");
	}

	/**
	 * Get cache region keys
	 * 
	 * @param region
	 *            : Cache region name
	 * @return key list
	 */
	@SuppressWarnings("rawtypes")
	public static List keys(String region) throws CacheException {
		return J2CACHE.keys(LEVEL_1, region);
	}

	/**
	 * 关闭到通道的连接
	 */
	public static void close() {
		J2CACHE.shutdown(LEVEL_1);
		J2CACHE.shutdown(LEVEL_2);
	}
	
}
